Here's another fun and confusing crash:
[adiumx.git] / Frameworks / Adium Framework / NDAppleScriptObject.m
blobab511644d6f46b3c8d71a3fc9c9b3ccedc750a20
1 /*
2  *  NDAppleScriptObject.m
3  *  NDAppleScriptObjectProjectAlpha
4  *
5  *  Created by Nathan Day on Mon May 17 2004.
6  *  Copyright (c) 2002 Nathan Day. All rights reserved.
7  */
9 #import "NDAppleScriptObject.h"
10 #import "NDProgrammerUtilities.h"
11 #import "NDResourceFork.h"
12 #import "NDComponentInstance.h"
13 #import "NSAppleEventDescriptor+NDAppleScriptObject.h"
14 #import "NSArray+NDUtilities.h"
16 static NSString         * kScriptResourceName = @"script";
17 static const short      kScriptResourceID = 128;
18 static const OSType     kScriptEditorCreatorCode = 'ToyS',
19                                                         kCompiledAppleScriptTypeCode = 'osas';
22  * category interface NDComponentInstance (Private)
23  */
24 @interface NDComponentInstance (Private)
25 - (ComponentInstance)instanceRecord;
26 @end
29  * class interface NDScriptData (Private)
30  */
31 @interface NDScriptData (Private)
32 + (id)newWithScriptID:(OSAID)scriptID componentInstance:(NDComponentInstance *)component;
33 + (id)scriptDataWithScriptID:(OSAID)scriptID componentInstance:(NDComponentInstance *)component;
34 + (Class)classForScriptID:(OSAID)scriptID componentInstance:(NDComponentInstance *)componentInstance;
35 - (id)initWithComponentInstance:(NDComponentInstance *)componentInstance;
36 - (id)initWithScriptID:(OSAID)scriptID componentInstance:(NDComponentInstance *)component;
37 - (OSAID)scriptID;
38 - (ComponentInstance)instanceRecord;
39 - (BOOL)isCompiled;
40 @end
42  * class interface NDScriptContext (Private)
43  */
44 @interface NDScriptContext (Private)
45 + (OSAID)compileString:(NSString *)string modeFlags:(long)modeFlags scriptID:(OSAID)scriptID componentInstance:(NDComponentInstance *)aComponentInstance;
46 - (id)initWithScriptID:(OSAID)aScriptDataID parentScriptContext:(NDScriptContext *)aParentScriptContext;
47 @end
50  * class interface NDScriptHandler (Private)
51  */
52 @interface NDScriptHandler (Private)
53 + (OSAID)compileString:(NSString *)aString scriptID:(OSAID)aScriptID componentInstance:(NDComponentInstance *)aComponentInstance;
54 + (OSAID)compileString:(NSString *)aString modeFlags:(long)aModeFlags scriptID:(OSAID)aScriptID componentInstance:(NDComponentInstance *)aComponentInstance;
55 - (void)setResultScriptDataID:(OSAID)aScriptDataID;
56 @end
59 @implementation NDAppleScriptObject
61 + (id)compileExecuteString:(NSString *)aString componentInstance:(NDComponentInstance *)aComponentInstance
63         return [[self compileExecuteSource:aString componentInstance:aComponentInstance] objectValue];
66 + (id)compileExecuteString:(NSString *)aString
68         return [[self compileExecuteSource:aString componentInstance:nil] objectValue];
71 - (id)initWithString:(NSString *)aString modeFlags:(long)aModeFlags componentInstance:(NDComponentInstance *)aComponentInstance
73         if( (self = [self initWithComponentInstance:aComponentInstance]) != nil )
74         {
75                 source = [aString retain];
76                 [self compileWithModeFlags:aModeFlags];
77         }
79         return self;
83 - (void)dealloc
85         [source release];
86         [error release];
87         [super dealloc];
90 - (NSDictionary *)error
92         if( error == nil )
93                 error = [[[self componentInstance] error] retain];
95         return error;
98 - (NSString *)source
100         return source ? source : [super source];
103 - (void)setSource:(NSString *)aSource
105         if( aSource != nil && source != aSource )
106         {
107                 [source release];
108                 source = [aSource retain];
109                 if( scriptID != kOSANullScript )
110                         NDLogOSStatus( OSADispose( [self instanceRecord], scriptID ));
111                 scriptID = kOSANullScript;
112         }
115 - (BOOL)compileWithModeFlags:(long)aModeFlags
117         if( ![self isCompiled] && source != nil )
118         {
119                 scriptID = [NDAppleScriptObject compileString:source modeFlags:aModeFlags scriptID:kOSANullScript componentInstance:[self componentInstance]];
121                 if( scriptID != kOSANullScript )
122                 {
123                         [source release];               // don't need the source anymore
124                         source = nil;
125                 }
126         }
128         return [self isCompiled];
131 - (BOOL)isCompiled
133         return scriptID != kOSANullScript;
136 - (BOOL)writeToURL:(NSURL *)aURL inDataFork:(BOOL)anInDataFork atomically:(BOOL)anAtomically
138         return anInDataFork
139                         ? [[self data] writeToURL:aURL atomically:anAtomically]
140                         : [self writeToURL:aURL Id:kScriptResourceID];
143 - (BOOL)writeToFile:(NSString *)aPath inDataFork:(BOOL)anInDataFork atomically:(BOOL)anAtomically
145         return anInDataFork
146                         ? [[self data] writeToFile:aPath atomically:anAtomically]
147                         : [self writeToFile:aPath Id:kScriptResourceID];
150 - (BOOL)writeToURL:(NSURL *)aURL Id:(short)anID
152         NSData                          * theData;
153         BOOL                                    theResult = NO,
154                 theCanNotWriteTo = NO;
156         if( [self isCompiled] && (theData = [self data]) )
157         {
158                 if( ![[NSFileManager defaultManager] fileExistsAtPath:[aURL path] isDirectory:&theCanNotWriteTo] )
159                 {
160                         theCanNotWriteTo = ![[NSFileManager defaultManager] createFileAtPath:[aURL path] contents:nil attributes:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedLong:kScriptEditorCreatorCode], NSFileHFSCreatorCode, [NSNumber numberWithUnsignedLong:kCompiledAppleScriptTypeCode], NSFileHFSTypeCode, nil]];
161                 }
163                 if( !theCanNotWriteTo )
164                         theResult = [theData writeToResourceForkURL:aURL type:kOSAScriptResourceType Id:anID name:kScriptResourceName];
165         }
167         return theResult;
171 - (BOOL)writeToFile:(NSString *)aPath Id:(short)anID
173         NSData                          * theData;
174         BOOL                                    theResult = NO,
175                 theCanNotWriteTo = NO;
177         if( [self isCompiled] && (theData = [self data]) )
178         {
179                 if( ![[NSFileManager defaultManager] fileExistsAtPath:aPath isDirectory:&theCanNotWriteTo] )
180                 {
181                         theCanNotWriteTo = ![[NSFileManager defaultManager] createFileAtPath:aPath contents:nil attributes:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedLong:kScriptEditorCreatorCode], NSFileHFSCreatorCode, [NSNumber numberWithUnsignedLong:kCompiledAppleScriptTypeCode], NSFileHFSTypeCode, nil]];
182                 }
184                 if( !theCanNotWriteTo )
185                         theResult = [theData writeToResourceForkFile:aPath type:kOSAScriptResourceType Id:anID name:kScriptResourceName];
186         }
188         return theResult;
191 + (NSString *)description
193         return @"AppleScript";
197  * -initWithScriptID:componentInstance:
198  */
199 - (id)initWithScriptID:(OSAID)aScriptID componentInstance:(NDComponentInstance *)aComponentInstance
201         if(NDLogFalse([[NDScriptData classForScriptID:aScriptID componentInstance:aComponentInstance] isSubclassOfClass:[NDScriptContext class]])
202                 && NDLogFalse(self = [self initWithComponentInstance:aComponentInstance]))
203         {
204                 scriptID = aScriptID;
205         }
206         else
207         {
208                 [self release];
209                 self = nil;
210         }
211         
212         return self;
215 @end
217 @implementation NDAppleScriptObject (NDExtended)
219 + (id)appleScriptObjectWithString:(NSString *)aString
221         return [[[ self alloc] initWithString:aString modeFlags:kOSAModeNull componentInstance:nil] autorelease];
224 + (id)appleScriptObjectWithString:(NSString *)aString componentInstance:(NDComponentInstance *)aComponentInstance
226         return [[[ self alloc] initWithString:aString modeFlags:kOSAModeNull componentInstance:aComponentInstance] autorelease];
229 + (id)appleScriptObjectWithData:(NSData *)aData
231         return [[[self alloc] initWithData:aData componentInstance:nil] autorelease];
234 + (id)appleScriptObjectWithData:(NSData *)aData componentInstance:(NDComponentInstance *)aComponentInstance
236         return [[[self alloc] initWithData:aData componentInstance:aComponentInstance] autorelease];
239 + (id)appleScriptObjectWithContentsOfFile:(NSString *)aPath
241         return [[[self alloc] initWithContentsOfFile:aPath componentInstance:nil] autorelease];
244 + (id)appleScriptObjectWithContentsOfFile:(NSString *)aPath componentInstance:(NDComponentInstance *)aComponentInstance
246         return [[[self alloc] initWithContentsOfFile:aPath componentInstance:aComponentInstance] autorelease];
249 + (id)appleScriptObjectWithContentsOfURL:(NSURL *)anURL
251         return [[[self alloc] initWithContentsOfURL:anURL componentInstance:nil] autorelease];
254 + (id)appleScriptObjectWithContentsOfURL:(NSURL *)anURL componentInstance:(NDComponentInstance *)aComponentInstance
256         return [[[self alloc] initWithContentsOfURL:anURL componentInstance:aComponentInstance] autorelease];
259 - (id)initWithString:(NSString *)aString componentInstance:(NDComponentInstance *)aComponentInstance
261         return [self initWithSource:aString modeFlags:kOSAModeNull componentInstance:aComponentInstance];
264 - (BOOL)compile
266         return [self compileWithModeFlags:kOSAModeNull];
269 @end